﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Hydra.Contract;
using mscoree;

namespace Hydra.Payload
{
    class HydraClient : IHydraCallback
    {
        public void WriteLog(string message)
        {
            Console.WriteLine("Server said: " + message);

            //Engine.Proxy.WriteLog(LogLevel.Debug, "...");
        }

        public void RunTask(string parameter)
        {
            Console.WriteLine("Server ask to run task: " + parameter);

            foreach (var domain in GetAppDomains())
            {
                Console.WriteLine(" Id:{0}, Name:{1}, Default:{2}, Trusted:{3}", domain.Id, domain.FriendlyName, domain.IsDefaultAppDomain(), domain.IsFullyTrusted);
            }

            // Try to invoke some method by reflection
            var mock = Type.GetType("Hydra.MockClientFX2.MockTest");
            if(mock == null)
                mock = Type.GetType("Hydra.MockClient.MockTest");

            if (mock != null)
            {
                var obj = Activator.CreateInstance(mock);
                mock.GetMethod("Execute").Invoke(obj, null);
            }
        }

        private static IList<AppDomain> GetAppDomains()
        {
            IList<AppDomain> list = new List<AppDomain>();
            IntPtr enumHandle = IntPtr.Zero;
            ICorRuntimeHost host = new CorRuntimeHost();
            try
            {
                host.EnumDomains(out enumHandle);
                object domain = null;
                while (true)
                {
                    host.NextDomain(enumHandle, out domain);
                    if (domain == null) break;
                    AppDomain appDomain = (AppDomain)domain;
                    list.Add(appDomain);
                }
                return list;
            }
            catch (Exception e)
            {
                Console.WriteLine("Failed to enumerate AppDomain: {0}", e.Message);
                return list;
            }
            finally
            {
                host.CloseEnum(enumHandle);
                Marshal.ReleaseComObject(host);
            }
        } 
    }
}
